package com.zeyu.framework.modules.sys.web;

import com.google.common.collect.Lists;

import com.zeyu.framework.core.persistence.Page;
import com.zeyu.framework.core.web.BaseController;
import com.zeyu.framework.core.web.Result;
import com.zeyu.framework.modules.sys.entity.Office;
import com.zeyu.framework.modules.sys.entity.Role;
import com.zeyu.framework.modules.sys.entity.User;
import com.zeyu.framework.modules.sys.service.OfficeService;
import com.zeyu.framework.modules.sys.service.SystemService;
import com.zeyu.framework.modules.sys.utils.UserUtils;
import com.zeyu.framework.utils.StringUtils;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

/**
 * 角色Controller
 */
@Controller
@RequestMapping(value = "/sys/role")
public class RoleController extends BaseController {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    @Autowired
    private SystemService systemService;

    @Autowired
    private OfficeService officeService;

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    @ModelAttribute("role")
    public Role get(@RequestParam(required = false) String id) {
        if (StringUtils.isNotBlank(id)) {
            return systemService.getRole(id);
        } else {
            return new Role();
        }
    }

    /**
     * 角色列表页
     */
    @RequiresPermissions("sys:role:view")
    @RequestMapping(value = "")
    public String index() {
        return "modules/sys/roleList";
    }

    /**
     * 角色列表
     */
    @RequiresPermissions("sys:role:view")
    @RequestMapping(value = "list")
    @ResponseBody
    public Page<Role> list(HttpServletRequest request) {

        Page<Role> page = new Page<>(request);

        List<Role> allRole = systemService.findAllRole();
        page.setList(allRole);
        page.setCount(allRole.size());

        return page;
    }

    /**
     * 保存角色
     */
    @RequiresPermissions("sys:role:edit")
    @RequestMapping(value = "save")
    @ResponseBody
    public Result save(@Validated Role role) {
        Result result = new Result();
        if (!UserUtils.getUser().isAdmin() && role.getSysData().equals(YES)) {
            result.setStatus(Result.ERROR);
            result.setMessage("越权操作，只有超级管理员才能修改此数据!");
            return result;
        }
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }

        if (!"true".equals(checkName(role.getOldName(), role.getName()))) {
            result.setStatus(Result.ERROR);
            result.setMessage("保存角色'" + role.getName() + "'失败, 角色名已存在");
            return result;
        }
        if (!"true".equals(checkEnname(role.getOldEnname(), role.getEnname()))) {
            result.setStatus(Result.ERROR);
            result.setMessage("保存角色'" + role.getName() + "'失败, 英文名已存在");
            return result;
        }
        systemService.saveRole(role);
        result.setStatus(Result.SUCCESS);
        result.setMessage("保存角色'" + role.getName() + "'成功");
        return result;
    }

    /**
     * 删除角色
     */
    @RequiresPermissions("sys:role:edit")
    @RequestMapping(value = "delete")
    @ResponseBody
    public Result delete(Role role) {
        Result result = new Result();
        if (!UserUtils.getUser().isAdmin() && role.getSysData().equals(YES)) {
            result.setStatus(Result.ERROR);
            result.setMessage("越权操作，只有超级管理员才能修改此数据!");
            return result;
        }
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }
        if (Role.isAdmin(role.getId())) {
            result.setStatus(Result.ERROR);
            result.setMessage("删除角色失败, 不允许内置角色或编号空!");
//        } else if (UserUtils.getUser().getRoleIdList().contains(role.getId())) {
//            result.setStatus(Result.ERROR);
//            result.setMessage("删除角色失败, 不能删除当前用户所在角色!");
        } else {
            systemService.deleteRole(role);
            result.setStatus(Result.SUCCESS);
            result.setMessage("删除角色成功");
        }

        return result;
    }

    /**
     * 获取角色选中的菜单列表
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "menuIds")
    public String getMenuIds(String id) {
        Role role = systemService.getRole(id);
        return role.getMenuIds();
    }


    /**
     * 保存角色的菜单列表
     *
     * @param role 角色
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "saveMenuIds")
    public Result saveMenuIds(Role role) {

        Result result = new Result();
        if (!UserUtils.getUser().isAdmin() && role.getSysData().equals(YES)) {
            result.setStatus(Result.ERROR);
            result.setMessage("越权操作，只有超级管理员才能修改此数据!");
            return result;
        }
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }

        systemService.saveRoleMenuIds(role);
        result.setStatus(Result.SUCCESS);
        result.setMessage("更新角色菜单成功");

        return result;
    }

    /**
     * 角色分配 -- 根据部门编号获取用户列表
     *
     * @param officeId 部门编号
     * @return 用户列表
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "officeUsers")
    public List<User> officeUsers(String officeId) {
        User user = new User();
        user.setOffice(new Office(officeId));

        return systemService.findUser(user);
    }

    /**
     * 角色分配 -- 获取当前角色的用户列表
     *
     * @param role 角色
     * @return 用户列表
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "roleUsers")
    public List<User> roleUsers(Role role) {
        User user = new User();
        user.setRole(role);

        return systemService.findUser(user);
    }

    /**
     * 保存角色的用户列表
     *
     * @param id 角色
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "assign")
    public Result assign(String id, String[] userIds) {

        Result result = new Result();
        Role role = systemService.getRole(id);
        if (!UserUtils.getUser().isAdmin() && role.getSysData().equals(YES)) {
            result.setStatus(Result.ERROR);
            result.setMessage("越权操作，只有超级管理员才能修改此数据!");
            return result;
        }
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }
        // 需要验证删除、添加和不变的三种
        List<User> userList = systemService.findUser(new User(role));
        List<User> addUserList = Lists.newArrayList();
        List<User> delUserList = Lists.newArrayList();
        // 返回信息
        StringBuilder builder = new StringBuilder("分配用户的角色操作完成,结果如下:<br/>");
        if (userIds == null || userIds.length == 0) {
            // 角色删除全部用户
            if (userList != null) {
                delUserList.addAll(userList.stream().map(user -> systemService.getUser(user.getId())).collect(Collectors.toList()));
            }
        } else {
            if (userList != null && userList.size() > 0) {
                // 找到需要添加的
                for (String userId : userIds) {
                    boolean exist = false;
                    for (User user : userList) {
                        if (StringUtils.equals(userId, user.getId())) {
                            exist = true;
                            break;
                        }
                    }
                    if (!exist) {
                        addUserList.add(systemService.getUser(userId));
                    }
                }
                // 找到需要删除的
                for (User user : userList) {
                    boolean exist = false;
                    for (String userId : userIds) {
                        if (StringUtils.equals(userId, user.getId())) {
                            exist = true;
                            break;
                        }
                    }
                    if (!exist) {
                        delUserList.add(systemService.getUser(user.getId()));
                    }
                }
            } else {
                // 全是新增加
                for (String userId : userIds) {
                    addUserList.add(systemService.getUser(userId));
                }
            }
        }

        int count = 0;
        for (User user : delUserList) {
            if (user.getRoleList().size() <= 1) {
                builder.append("用户【").append(user.getName()).append("】从角色【")
                        .append(role.getName()).append("】中移除失败,这已经是用户的唯一角色,不可移除!<br/>");
            } else {
                boolean flag = systemService.outUserInRole(role, user);
                if (flag) {
                    builder.append("用户【").append(user.getName()).append("】从角色【")
                            .append(role.getName()).append("】中移除成功!<br/>");
                    count++;
                } else {
                    builder.append("用户【").append(user.getName()).append("】从角色【")
                            .append(role.getName()).append("】中移除失败!<br/>");
                }
            }
        }
        // 无操作
        if (addUserList.size() == 0 && delUserList.size() == 0) {
            builder.append("角色无用户分配");
        }
        if (count > 0)
            builder.append("已经成功从角色【").append(role.getName()).append("】移除【")
                    .append(count).append("】个用户!");
        count = 0;
        for (User user : addUserList) {
            User res = systemService.assignUserToRole(role, user);
            if (res != null) {
                builder.append("新增用户【").append(user.getName()).append("】到角色【")
                        .append(role.getName()).append("】中成功!<br/>");
                count++;
            }
        }
        if (count > 0)
            builder.append("已经成功从角色【").append(role.getName()).append("】增加【")
                    .append(count).append("】个用户!");

        result.setStatus(Result.SUCCESS);
        result.setMessage(builder.toString());

        return result;
    }

    /**
     * 验证角色名是否有效
     *
     * @param oldName 旧名称
     * @param name    新名称
     * @return 有效
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "checkName")
    public String checkName(String oldName, String name) {
        if (name != null && name.equals(oldName)) {
            return "true";
        } else if (name != null && systemService.getRoleByName(name) == null) {
            return "true";
        }
        return "false";
    }

    /**
     * 验证角色英文名是否有效
     *
     * @param oldEnname 原名称
     * @param enname    新名称
     * @return 有效
     */
    @RequiresPermissions("user")
    @ResponseBody
    @RequestMapping(value = "checkEnname")
    public String checkEnname(String oldEnname, String enname) {
        if (enname != null && enname.equals(oldEnname)) {
            return "true";
        } else if (enname != null && systemService.getRoleByEnname(enname) == null) {
            return "true";
        }
        return "false";
    }

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================
}
